//
//  ElectronicNote.hpp
//  XML
//
//  Created by ling on 2024/7/18.
//

#ifndef ElectronicNote_h
#define ElectronicNote_h

#include <stdio.h>
#include <string>
#include <map>
#include <cstdlib>
#include "stdlib.h"
#include "tinyxml2.h"

struct ElectronicStepModel {
    const char* preStep;
    const char* step;
    const char* nextStep;
};

struct ElectronicFifthModel {
    int position;
    int fifths;
    const char* fifth;
    const char* fifthChar;
};

class ElectronicAnalyzeTool {
    
public:
    
    std::vector<ElectronicFifthModel> fifthsList = {
        ElectronicFifthModel { 0 , -6, "bG", "-6"},
        ElectronicFifthModel { 1 , 1, "G", "1"},
        ElectronicFifthModel { 2 , -4, "bA", "-4"},
        ElectronicFifthModel { 3 , 3, "A", "3"},
        ElectronicFifthModel { 4 , -2, "bB", "-2"},
        ElectronicFifthModel { 5 , 5, "B", "5"},
        ElectronicFifthModel { 6 , 0, "C", "0"},
        ElectronicFifthModel { 7 , 7, "#C", "7"},
        ElectronicFifthModel { 8 , 2, "D", "2"},
        ElectronicFifthModel { 9 , -3, "bE", "-3"},
        ElectronicFifthModel { 10 , 4, "E", "4"},
        ElectronicFifthModel { 11 , -1, "F", "-1"},
        ElectronicFifthModel { 12 , 6, "#F", "6"},
    };
    
    std::vector<std::vector<const char *>> simpleKeyList = {
        {"F#", "G#m", "A#m", "B", "C#", "D#m", "E#mb5", "F#m", "G#", "A#", "Bm", "C#m", "F#7", "C#7", "D#"},
        {"G", "Am", "Bm", "C", "D", "Em", "F#mb5", "Gm", "A", "B", "Cm", "Dm", "G7", "D7", "E"},
        {"Ab", "Bbm", "Cm", "Db", "Eb", "Fm", "Gmb5", "Abm", "Bb", "C", "Dbm", "Ebm", "Ab7", "Eb7", "F"},
        {"A", "Bm", "C#m", "D", "E", "F#m", "G#mb5", "Am", "B", "C#", "Dm", "Em", "A7", "E7", "F#"},
        {"Bb", "Cm", "Dm", "Eb", "F", "Gm", "Amb5", "Bbm", "C", "D", "Ebm", "Fm", "Bb7", "F7", "G"},
        {"B", "C#m", "D#m", "E", "F#", "G#m", "A#mb5", "Bm", "C#", "D#", "Em", "F#m", "B7", "F#7", "G#"},
        {"C", "Dm", "Em", "F", "G", "Am", "Bmb5", "Cm", "D", "E", "Fm", "Gm", "C7", "G7", "A"},
        {"C#", "D#m", "E#m", "F#", "G#", "A#m", "B#mb5", "C#m", "D#", "E#", "F#m", "G#m", "C#7", "G#7", "A#"},
        {"D", "Em", "F#m", "G", "A", "Bm", "C#mb5", "Dm", "E", "F#", "Gm", "Am", "D7", "A7", "B"},
        {"Eb", "Fm", "Gm", "Ab", "Bb", "Cm", "Dmb5", "Ebm", "F", "G", "Abm", "Bbm", "Eb7", "Bb7", "C"},
        {"E", "F#m", "G#m", "A", "B", "C#m", "D#mb5", "Em", "F#", "G#", "Am", "Bm", "E7", "B7", "C#"},
        {"F", "Gm", "Am", "Bb", "C", "Dm", "Emb5", "Fm", "G", "A", "Bbm", "Cm", "F7", "C7", "D"},
        {"F#", "G#m", "A#m", "B", "C#", "D#m", "E#mb5", "F#m", "G#", "A#", "Bm", "C#m", "F#7", "C#7", "D#"}
    };
    
    /// 生成移调文件，如果成功，返回1
    /// - Parameters:
    ///   - xmlPath: 初始xml地址
    ///   - savePath: 保存的xml地址
    ///   - position: 移多少位
    int analyzeXML(const char* xmlPath, const char* savePath, int position) const;
    
    /// 获取曲谱的原调
    /// - Parameter xmlPath: 曲谱的地址
    const char* analyzeKey(const char* xmlPath) const;
    
    ElectronicStepModel matchWordModel(int stepValue) const;
    
    int wordValue(const char* word) const;
        
};

#endif /* ElectronicNote_hpp */
